#include "des.h"
#include "qdebug.h"
#include<iostream>
#include<fstream>
#include<bitset>
#include<string>
#include <QtGlobal>
using namespace std;






Des::Des()
{

}

bitset<28> leftwing(bitset<28> str){
    bitset<28> res;
    for(int i=0;i<28;i++){
        res[i]=str[(i-1+28)%28];
    }
    return res;
}

bitset<64> Des::charToBitset(const char s[8])
{
    bitset<64> bits;
    for(int i=0; i<8; ++i)
        for(int j=0; j<8; ++j)
            bits[i*8+j] = ((s[i]>>j) & 1);
    return bits;
}

void Des:: generalkey(){
    bitset<56> masterkey,inter;
    bitset<28> left,right;

    //PC_1
    for(int i=0;i<56;i++){
        qDebug()<<"gen"<<i;
        masterkey[i]=key[64-pc1[55-i]];
    }

    for(int i=0;i<28;i++){
        right[i]=masterkey[i];
    }
    for(int i=28;i<56;i++){
        left[i-28]=masterkey[i];
    }

    for(int i=0;i<16;i++){
        left=leftwing(left);
        right=leftwing(right);
        if(!(i+1==1||i+1==2||i+1==9||i+1==16)){
            left=leftwing(left);
            right=leftwing(right);
        }
        for(int j=0;j<28;j++){
            inter[j]=right[j];
        }
        for(int j=28;j<56;j++){
            inter[j]=left[j-28];
        }
        //PC_2
        for(int j=0;j<48;j++){
            subkey[i][j]=inter[56-pc2[47-j]];
        }
    }
}

bitset<64> Des::encryt(bitset<64> &txt){
    //IP
    bitset<64> inter,ctxt;
    bitset<32> lt,rt;
    for(int i=0;i<64;i++){
        inter[i]=txt[64-ip[63-i]];
    }

    for(int i=0;i<32;i++){
        rt[i]=inter[i];
    }
    for(int i=32;i<64;i++){
        lt[i-32]=inter[i];
    }

    for(int tag=0;tag<16;tag++){
        //EBOX
        bitset<48> aftere;
        for(int i=0;i<48;i++){
            aftere[i]=rt[32-ebox[47-i]];
        }

        aftere=aftere^subkey[tag];
        //sbox
        bitset<32> afters;
        int x=0;
        for(int i=0;i<48;i+=6){
            int col=aftere[i+1]+aftere[i+2]*2+aftere[i+3]*4+aftere[i+4]*8;
            int row=aftere[i]+aftere[i+5]*2;
            bitset<4> num(sbox[7-i/6][row][col]);

            afters[x]=num[0];
            afters[x+1]=num[1];
            afters[x+2]=num[2];
            afters[x+3]=num[3];
            x+=4;

        }
        //PBOX
        bitset<32> afterp;
        for(int i=0;i<32;i++){
            afterp[i]=afters[32-pbox[31-i]];
        }

        afterp=afterp^lt;
        lt=rt;
        rt=afterp;
    }

    for(int i=0;i<32;i++){
        inter[i]=lt[i];
    }
    for(int i=32;i<64;i++){
        inter[i]=rt[i-32];
    }
    //IP-1
    for(int i=0;i<64;i++){
        ctxt[i]=inter[64-ip_1[63-i]];
    }
    return ctxt;
}

bitset<64> Des::decryt(bitset<64> &txt){
    //IP
    bitset<64> inter,ptxt;
    bitset<32> lt,rt;
    for(int i=0;i<64;i++){
        inter[i]=txt[64-ip[63-i]];
    }

    for(int i=0;i<32;i++){
        rt[i]=inter[i];
    }
    for(int i=32;i<64;i++){
        lt[i-32]=inter[i];
    }

    for(int tag=0;tag<16;tag++){
        //EBOX
        bitset<48> aftere;
        for(int i=0;i<48;i++){
            aftere[i]=rt[32-ebox[47-i]];
        }

        aftere=aftere^subkey[15-tag];
        //sbox
        bitset<32> afters;
        int x=0;
        for(int i=0;i<48;i+=6){
            int col=aftere[i+1]+aftere[i+2]*2+aftere[i+3]*4+aftere[i+4]*8;
            int row=aftere[i]+aftere[i+5]*2;
            bitset<4> num(sbox[7-i/6][row][col]);
            afters[x]=num[0];
            afters[x+1]=num[1];
            afters[x+2]=num[2];
            afters[x+3]=num[3];
            x+=4;

        }
        //PBOX
        bitset<32> afterp;
        for(int i=0;i<32;i++){
            afterp[i]=afters[32-pbox[31-i]];
        }
        afterp=afterp^lt;
        lt=rt;
        rt=afterp;
    }

    for(int i=0;i<32;i++){
        inter[i]=lt[i];
    }
    for(int i=32;i<64;i++){
        inter[i]=rt[i-32];
    }

    for(int i=0;i<64;i++){
        ptxt[i]=inter[64-ip_1[63-i]];
    }
    return ptxt;
}
